<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- 使数组和能被 P 整除 -->
    <script>
      /*
        思路：
        先将所有元素和除以p后的余数存为mod
        遍历时，把当前i的前面的元素和（不包括第i个元素）除以p后的余数preSumMod_i存起来，
        当出现某个j，满足前j个元素和除以p后的余数(preSumMod_j - mod) % p = preSumMod_i 时，
        相当于两个下标之间的元素和除以p后的余数正好是全部元素和除以p后的余数，其他元素和刚好能被p整除，
        所以要删的元素就是两个下标之间的元素。
      */
      var minSubarray = function (nums, p) {
        const n = nums.length
        let mod = nums.reduce((a, b) => (a % p) + (b % p)) % p
        if (mod === 0) {
          return 0
        }
        const map = new Map()
        let preSumMod = 0
        let res = n
        for (let i = 0; i < n; i++) {
          map.set(preSumMod, i) // 键为前i个元素的和除以p后的余数，下标：[0,1,...,i-1]
          preSumMod = (preSumMod + nums[i]) % p
          if (map.has((preSumMod - mod + p) % p)) {
            // 如果当前(preSumMod_j - mod) % p 正好等于 前i个元素和除以p后的余数preSumMod_i，找到最后一次出现时的下标i，计算两个下标中间的元素个数，更新res
            res = Math.min(res, i - map.get((preSumMod - mod + p) % p) + 1)
          }
        }
        return res === n ? -1 : res
      }
      console.log(minSubarray([3, 1, 4, 2], 6))
    </script>
  </body>
</html>
